import os
import sys
from osgeo import gdal
import numpy as np
from gdalconst import *
import psycopg2
from os.path import basename
import datetime
#import constant
import shutil



apom_host='192.168.0.4'
apom_database='fimo'
apom_user='rasdaman'
apom_password='rasdaman'

HOME_DIR = "/media/phamha/32F426F53CAD8B16/"
#HOME_DIR = "/var/www/html/"
ORG_DIR = "fimo/apom/Original/SatOrgVIIRSTemp/"
RESAMP_DIR = "fimo/apom/Resample/SatResampVIIRSTemp/"
ras_cmd = "/usr/lib/postgresql/9.1/bin/raster2pgsql -a -f rasref -F {0} apom.satresampviirstemperature"
insert_query = "INSERT INTO {0}(aqstime, rasref, filename, filepath, gridid,orgid,projection) VALUES ('{1}'::timestamp, '{2}'::raster, '{3}', '{4}', 6000, 1, 1)" 
#check file valid
def check_file(h5file):
	dataset = "HDF5:" + h5file + "://All_Data/VIIRS-LST-EDR_All/LandSurfaceTemperature"
	lad = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Latitude"
	lod = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Longitude"
	x = os.system("gdalinfo {0}".format(dataset))
	y = os.system("gdalinfo {0}".format(lad))
	z = os.system("gdalinfo {0}".format(lad))
	
	if x==256 or y ==256 or z ==256:
		return 1
	else:
		return 0

#insert to database
def insertToDB(query):
	con = None
	mess =""
	try:
		con = psycopg2.connect(host=apom_host, database = apom_database, user= apom_user, password=apom_password) 
		
		#con = psycopg2.connect(host=constant.host, database = constant.database, user= constant.user, password=constant.password) 
		cur = con.cursor()		
		cur.execute(query)		
		con.commit()
		mess = "0"
	except psycopg2.Error as e: 
		mess = e
	finally:
		if con:
			con.close()
	return mess

# convert from file name to timestamp
def ConvertToTimestamp(filename):
	year = filename[17:21]
	month = filename[21:23]
	day = filename[23:25]
	hour = filename[36:38]
	minute = filename[38:40]
	second = filename[40:42]
	times = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second
	return times
# convert from file name to timestamp
def getYear(filename):
	year = filename[17:21]
	return year
# get bounding coordinates
def GetBoundingCoors(lad, lod):

	gran1 = gdal.Open(lad, GA_ReadOnly)
	gran4 = gdal.Open(lod, GA_ReadOnly)

	latitude = np.array(gran1.ReadAsArray())
	longitude = np.array(gran4.ReadAsArray())

	la = np.ma.masked_equal(latitude, -999.3, copy=False)
	lo = np.ma.masked_equal(longitude, -999.3, copy=False)

	coors = []
	coors.append(np.amax(la))
	coors.append(np.amin(la))
	coors.append(np.amax(lo))
	coors.append(np.amin(lo))

	return coors

# retrieve LST dataset with uncorrect GCPs
def Hdf5ToImgUGCPs(h5file):
	if not os.path.isfile(h5file):
		print "Error: {0} is not a valid image file".format(h5file)
		return 1

	dataset = "HDF5:" + h5file + "://All_Data/VIIRS-LST-EDR_All/LandSurfaceTemperature"
	lad = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Latitude"
	lod = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Longitude"
	try:
		gdal.Open(dataset, GA_ReadOnly)
		gdal.Open(lad, GA_ReadOnly)
		gdal.Open(lod, GA_ReadOnly)
		
		coors = GetBoundingCoors(lad, lod)
		# write corners to file
		coorfname = h5file[:-3] + "_LST_corner.txt"
		fi = open(coorfname, "w")
		fi.write("{0} {1}, {2} {3}, {4} {5}, {6} {7}".format(str(coors[0]), str(coors[3]), str(coors[0]), str(coors[2]), str(coors[1]), str(coors[2]), str(coors[1]), str(coors[3])))
		fi.close()

		# write LST dataset to image
		imgfname = h5file[:-3] + "_LST.raw"
		command = "gdal_translate -of GTiff {0} {1}".format(dataset, imgfname)
		status = os.system(command)

		if status == 0: # success to extract data to image
			return imgfname
		return 1 # in case of error
	except IOError as e: 
		return 1
# correct GCPs for raw image
def CorrectGCPs(imgfname):
	dataset = gdal.Open(imgfname, GA_ReadOnly)	
	if dataset is None:
		print ('Couldnt open file: {1}\n'.format(imgfname))
		return 1
	data = dataset.ReadAsArray()
	cols = dataset.RasterXSize
	rows = dataset.RasterYSize
	
	# get GCP points	
	gcps = dataset.GetGCPs()
	refine_gcps = []
	for gcp in gcps:
		if gcp.GCPX != 0 and gcp.GCPX != -999.3 and gcp.GCPY != 0 and gcp.GCPY != -999.3:
			gcp.GCPX = gcp.GCPX - 180
			refine_gcps.append(gcp)
		
	# convert DNs to LST
	datal = np.zeros((rows, cols), dtype=np.float32)
	scale = float(0.0025455155)
	offset = float(183.2)

	# calculate aot value with offset and scale
	for i in range(0, rows):
		for j in range(0, cols):
			if data[i,j] <= 0 or data[i,j] > 65000:
				datal[i,j] = -32768
			else:
				datal[i,j] = scale*data[i,j] + offset
		
	# create output file
	correctedfname = imgfname[:-4] + ".rec"
	gtiff = gdal.GetDriverByName('GTiff')
	output = gtiff.Create(correctedfname, cols, rows, 1, gdal.GDT_Float32)
	if output is None:
		print ("can't create corrected GCP file: {1}\n".format(correctedfname))
		return 1
	output.SetGCPs(tuple(refine_gcps), output.GetProjection())
	output.GetRasterBand(1).WriteArray(datal)
		
	return correctedfname

# create VRT for GCP corrected image
def CreateVRT(imgfname):
	if not os.path.isfile(imgfname):
		print "Can't create VRT file for: {0}\n".format(imgfname)
		return 1
	vrtfname = imgfname[:-4] + ".vrt"
	os.system("gdal_translate -of VRT {0} {1}".format(imgfname, vrtfname))
	return vrtfname

# create tiff full and PNG, metadata file
def CreateTiffFull(vrtfname):
	correctedfname = vrtfname[:-4] + ".raw"
	if not os.path.isfile(vrtfname) and not os.path.isfile(correctedfname):
		print "Can't create Tiff full: {0} or {1} is not useful data".format(vrtfname, correctedfname)
		return 1
	# name for files to store with original HDF5 data
	tiffull = vrtfname[:-4] + ".tif"
	metadata = tiffull[:-4] + "_metadata.txt"
	pngori = tiffull[:-4] + "_convert.png"
	pnglarge = tiffull[:-4] + "_thumbnail.png"
	# create files to store
	os.system("gdalwarp -of GTiff -tps {0} {1}".format(vrtfname, tiffull))
	os.system("gdalinfo {0} > {1}".format(tiffull, metadata))
	os.system("gdal_translate -of PNG -ot Byte {0} {1}".format(tiffull, pngori))
	os.system("gdal_translate -of PNG -ot Byte -outsize 500 450 {0} {1}".format(tiffull, pnglarge))

	return 0

# resample VietNam
def CreateResample(vrtfname):
	correctedfname = vrtfname[:-4] + ".raw"
	if not os.path.isfile(vrtfname) and not os.path.isfile(correctedfname):
		print "Can't create resample image: {0} or {1} is not useful data".format(vrtfname, correctedfname)
		return 1
	# create resample data
	resampfname = vrtfname[:-4] + "_resample.tif" 
	os.system("gdalwarp -t_srs '+proj=longlat +datum=WGS84' -tps -ot Float32 -wt Float32 -te 100.1 6.4 111.8 25.6 -tr 0.05 -0.05 -r bilinear -srcnodata -32768 -dstnodata -32768 -overwrite -multi {0} {1}".format(vrtfname, resampfname))

	return 0
#insert org temp data to DB

def insert_org_temp(logfile, h5file):
		flog = open(logfile, "a")
		
		lad = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Latitude"
		lod = "HDF5:" + h5file + "://All_Data/VIIRS-MOD-GEO-TC_All/Longitude"
		coors = GetBoundingCoors(lad, lod)
		filename = basename(h5file)
		aqstime = ConvertToTimestamp(filename)
		year = getYear(filename)
		path = ORG_DIR + year + "/" + filename[:-3] + "/"
		#move h5 file to images folder
		dest_folder = HOME_DIR + path
		if not os.path.exists(dest_folder):
			os.makedirs(dest_folder)
		shutil.move(h5file,dest_folder)
		
		tiffull = h5file[:-3] + "_LST.tif"
		metadata = h5file[:-3] + "_LST_metadata.txt"
		pngori = h5file[:-3] + "_LST_convert.png"
		pnglarge = h5file[:-3] + "_LST_thumbnail.png"
		cornerfile = h5file[:-3] + "_LST_corner.txt"
		
		
		if os.path.isfile(tiffull):
			shutil.move(tiffull,dest_folder)
		if os.path.isfile(metadata):
			shutil.move(metadata,dest_folder)
		if os.path.isfile(pngori):
			shutil.move(pngori,dest_folder)
		if os.path.isfile(pnglarge):
			shutil.move(pnglarge,dest_folder)
		if os.path.isfile(cornerfile):
			shutil.move(cornerfile,dest_folder)
		
		#insert infomation to db
		t = datetime.datetime.now().replace(tzinfo=None)
		in_time = t.strftime('%Y-%m-%d %H:%M:%S')
		sql = "INSERT INTO apom.satorgviirstemperature(typeid, aqstime, filename, path, corner) VALUES(1, '{0}', '{1}', '{2}', ST_GeomFromText('POLYGON(( {3} {4}, {5} {6}, {7} {8}, {9} {10}, {11} {12}))', 4326))".format(aqstime, filename, path, str(coors[0]), str(coors[3]), str(coors[0]), str(coors[2]), str(coors[1]), str(coors[3]), str(coors[1]), str(coors[2]), str(coors[0]), str(coors[3])) 
		
		mess = insertToDB(sql)
		#write to log
		if(mess=="0"):
			log = "[{0}] successfully inserted information of {1} into database\n".format(in_time, filename)
			flog.write(log)
			print(log)
		else:
			log = "[{0}] can't insert {1} to database server: {2}\n".format(in_time, filename, str(mess))
			flog.write(log)
			print(log)
			return 0
		flog.close()
		return 1
# insert resample image
def insert_resample_temp(logfile, tiffile):
	flog = open(logfile, "a")

	cmd = ras_cmd.format(tiffile)
	aod_script = os.popen(cmd).read()
	first_index = aod_script.find("('")
	last_index = aod_script.find("':")
	aod_ref = aod_script[first_index+2:last_index]
		
	filename = basename(tiffile)
	aqstime = ConvertToTimestamp(filename)
	year = getYear(filename)
	path = RESAMP_DIR + year + "/" + filename[:-17] + "/"
	t = datetime.datetime.now().replace(tzinfo=None)
	in_time = t.strftime('%Y-%m-%d %H:%M:%S')
	
	#move h5 file to images folder
	dest_folder = HOME_DIR + path
	if not os.path.exists(dest_folder):
		os.makedirs(dest_folder)
	shutil.move(tiffile,dest_folder)
				
	temp_query = insert_query.format("apom.satresampviirstemperature",aqstime,aod_ref,filename,path)
	
	mess = insertToDB(temp_query)
	#write to log
	if(mess=="1"):
		log = "[{0}] successfully inserted information of {1} into database\n".format(in_time, filename)
		flog.write(log)
		print(log)
	else:
		log = "[{0}] can't insert {1} to database server: {2}\n".format(in_time, filename, str(mess))
		flog.write(log)
		print(log)
		return 0
	flog.close()
	return 1

def remove_temp_file(logfile, h5file):
	
		temp_file = h5file[:-3]+"_LST.raw"
		
		if os.path.isfile(temp_file):
			os.remove(temp_file)
		temp_file = h5file[:-3]+"_LST.rec"
		
		if os.path.isfile(temp_file):
			os.remove(temp_file)
		temp_file = h5file[:-3]+"_LST.vrt"
	
		if os.path.isfile(temp_file):
			os.remove(temp_file)
		temp_file = h5file[:-3]+"_LST_aux.xml"
	
		if os.path.isfile(temp_file):
			os.remove(temp_file)
		
def process_all(logfile,file_name):
	print "create corner"
	a = Hdf5ToImgUGCPs(file_name)
	print "corect GCP"
	b = CorrectGCPs(a)
	print "create VRT"
	c = CreateVRT(b)
	#CreateTiffFull(c)
	print "create resample"
	CreateResample(c)
	print "insert org to db"
	insert_org_temp(logfile,file_name)
	print "insert res to db"
	res_file = file_name[:-3] + "_LST_resample.tif"
	insert_resample_temp(logfile,res_file)
	remove_temp_file(logfile,file_name)
"""

log = "/home/phamha/Desktop/b/log.txt"
directory = "/home/phamha/Desktop/b/"

t = datetime.datetime.now().replace(tzinfo=None)
in_time = t.strftime('%Y-%m-%d %H:%M:%S')
print(in_time)

h5files = [f for f in os.listdir(directory) if f.endswith('.h5')]

for f in h5files:
	filename = directory + f
	if check_file(filename)==1:
		os.remove(filename)	
	else:
		process_all(log,filename)

t = datetime.datetime.now().replace(tzinfo=None)
in_time = t.strftime('%Y-%m-%d %H:%M:%S')
print(in_time)

"""


directory = "/home/phamha/Desktop/a/"

t = datetime.datetime.now().replace(tzinfo=None)
in_time = t.strftime('%Y-%m-%d %H:%M:%S')
print(in_time)

h5files = [f for f in os.listdir(directory) if f.endswith('.h5')]
h5files.sort()
for f in h5files:
	filename = directory + f

	print filename

t = datetime.datetime.now().replace(tzinfo=None)
in_time = t.strftime('%Y-%m-%d %H:%M:%S')
print(in_time)



